/**
 * Generali Solutions d'assurances - Tous droits réservés &copy; 2007 - 2010
 */
package fr.generali.accueilclient.commun.handler;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import fr.generali.accueilclient.commun.exception.AccueilClientBusinessException;
import fr.generali.accueilclient.commun.request.Request;

/**
 * @author Holmes Kelly
 * @param <S> object to request
 */
public abstract class AbstractHandlerRequest<S> {
    /**
     * Boolean indiquant si l'handler a bien exécuté la request
     */
    private boolean isProcessed;

    /**
     * @param request request
     * @throws AccueilClientBusinessException exception business
     */
    public void handleRequest(Request< ? > request) throws AccueilClientBusinessException {
        setProcessed(processRequest(request));
    }

    /**
     * @param request request
     * @return true if the specific handler handles the request
     * @throws AccueilClientBusinessException exception business
     */
    protected abstract boolean processRequest(Request< ? > request) throws AccueilClientBusinessException;

    /**
     * @author Holmes Kelly
     */
    public static class Dispactcher {

        /**
         * liste de handlers
         */
        private List<AbstractHandlerRequest< ? >> handlers = new LinkedList<AbstractHandlerRequest< ? >>();

        /**
         * @param handlerRequest handler request
         */
        public void addHandler(AbstractHandlerRequest< ? > handlerRequest) {
            handlers.add(handlerRequest);
        }

        /**
         * Request is handled by all handlers
         * 
         * @param request request
         * @throws AccueilClientBusinessException exception business
         */
        public void handleRequest(Request< ? > request) throws AccueilClientBusinessException {

            for (Iterator<AbstractHandlerRequest< ? >> iterate = handlers.iterator(); iterate.hasNext();) {

                AbstractHandlerRequest< ? > handlerRequest = (AbstractHandlerRequest< ? > ) (iterate.next());

                // execution de l'HandleRequest
                handlerRequest.handleRequest(request);
            }
        }

        /**
         * @param request request
         * @return true if request is handled by one of the handler from the
         *         list of handlers
         * @throws AccueilClientBusinessException exception business
         */
        public boolean handleRequestWithInterruption(Request< ? > request) throws AccueilClientBusinessException {

            for (Iterator<AbstractHandlerRequest< ? >> iterate = handlers.iterator(); iterate.hasNext();) {

                AbstractHandlerRequest< ? > handlerRequest = (AbstractHandlerRequest< ? > ) (iterate.next());

                // execution de l'HandleRequest
                handlerRequest.handleRequest(request);

                if (handlerRequest.isProcessed) {
                    return true;
                }
            }
            return false;
        }

    }

    /**
     * @return the isProcessed
     */
    public Boolean getIsProcessed() {
        return isProcessed;
    }

    /**
     * @param isProcessed the isProcessed to set
     */
    protected void setProcessed(boolean isProcessed) {
        this.isProcessed = isProcessed;
    }

}
